home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 93 / applic / sdbmth.c < prev    next >
C/C++ Source or Header  |  1987-01-15  |  7KB  |  351 lines

  1. /* SDBMTH.C - string arithmetic routines */
  2.  
  3. #include "sdbio.h"
  4.  
  5. /* db_cmp - compare two signed numeric strings */
  6. int db_cmp(arg1,arg2)
  7.   char *arg1,*arg2;
  8. {
  9.     int sign1,sign2;
  10.  
  11.     /* get the signs of the arguments */
  12.     sign1 = getsign(&arg1);
  13.     sign2 = getsign(&arg2);
  14.  
  15.     /* compute the result */
  16.     if (sign1 == sign2) {
  17.     if (sign1 == 1)
  18.         return (compare(arg1,arg2));
  19.     else
  20.         return (compare(arg2,arg1));
  21.     }
  22.  
  23.     /* signs are different */
  24.     return (sign1);
  25. }
  26.  
  27. /* db_add - add two signed numeric strings */
  28. db_add(result,arg1,arg2)
  29.   char *result,*arg1,*arg2;
  30. {
  31.     int signr,sign1,sign2;
  32.     char rtmp[NUMBERMAX+2],*rptr;
  33.  
  34.     /* get the signs of the arguments */
  35.     sign1 = getsign(&arg1);
  36.     sign2 = getsign(&arg2);
  37.  
  38.     /* compute the result */
  39.     if (sign1 == sign2) {
  40.     signr = sign1;
  41.     add(rtmp,arg1,arg2);
  42.     }
  43.     else
  44.     switch (compare(arg1,arg2)) {
  45.     case -1:
  46.         signr = sign2;
  47.         sub(rtmp,arg2,arg1);
  48.         break;
  49.     case 0:
  50.         strcpy(result,"0");
  51.         return;
  52.     case 1:
  53.         signr = sign1;
  54.         sub(rtmp,arg1,arg2);
  55.         break;
  56.     }
  57.  
  58.     /* insert the sign */
  59.     if (signr == -1)
  60.     strcpy(result,"-");
  61.     else
  62.     result[0] = 0;
  63.  
  64.     /* eliminate possible leading zeros */
  65.     for (rptr = rtmp; *rptr == '0'; rptr++)
  66.     ;
  67.  
  68.     /* copy the result */
  69.     if (*rptr != 0)
  70.     strcat(result,rptr);
  71.     else
  72.     strcat(result,"0");
  73. }
  74.  
  75. /* db_sub - subtract two signed numeric strings */
  76. db_sub(result,arg1,arg2)
  77.   char *result,*arg1,*arg2;
  78. {
  79.     int signr,sign1,sign2;
  80.     char rtmp[NUMBERMAX+2],*rptr;
  81.  
  82.     /* get the signs of the arguments */
  83.     sign1 = getsign(&arg1);
  84.     sign2 = getsign(&arg2);
  85.  
  86.     /* invert the sign of arg2 */
  87.     sign2 = -sign2;
  88.  
  89.     /* compute the result */
  90.     if (sign1 == sign2) {
  91.     signr = sign1;
  92.     add(rtmp,arg1,arg2);
  93.     }
  94.     else
  95.     switch (compare(arg1,arg2)) {
  96.     case -1:
  97.         signr = sign2;
  98.         sub(rtmp,arg2,arg1);
  99.         break;
  100.     case 0:
  101.         strcpy(result,"0");
  102.         return;
  103.     case 1:
  104.         signr = sign1;
  105.         sub(rtmp,arg1,arg2);
  106.         break;
  107.     }
  108.  
  109.     /* insert the sign */
  110.     if (signr == -1)
  111.     strcpy(result,"-");
  112.     else
  113.     result[0] = 0;
  114.  
  115.     /* eliminate a possible leading zero */
  116.     for (rptr = rtmp; *rptr == '0'; rptr++)
  117.     ;
  118.  
  119.     /* copy the result */
  120.     if (*rptr != 0)
  121.     strcat(result,rptr);
  122.     else
  123.     strcat(result,"0");
  124. }
  125.  
  126. /* add - add two unsigned numeric strings */
  127. static add(result,arg1,arg2)
  128.   char *result,*arg1,*arg2;
  129. {
  130.     char *vr,*v1,*v2,*vx;
  131.     int carry,i,nmin,nmax,nd1,nd2;
  132.  
  133.  
  134.     /* get number of digits in each argument */
  135.     nd1 = getlen(arg1);
  136.     nd2 = getlen(arg2);
  137.  
  138.     /* compute the address of the last digit + 1 */
  139.     v1 = arg1 + nd1;
  140.     v2 = arg2 + nd2;
  141.  
  142.     /* compute minimum and maximum of nd1 and nd2 */
  143.     if (nd1 < nd2) {
  144.     nmin = -nd1;
  145.     nmax = -nd2;
  146.     vx = v2;
  147.     }
  148.     else {
  149.     nmin = -nd2;
  150.     nmax = -nd1;
  151.     vx = v1;
  152.     }
  153.  
  154.     /* compute the address of the last result digit + 1 */
  155.     vr = result - nmax; vr[0] = 0;
  156.  
  157.     /* initialize the carry */
  158.     carry = 0;
  159.  
  160.     /* add the digits */
  161.     for (i = -1; i >= nmin; i--) {
  162.  
  163.     /* check for decimal point */
  164.     if (v1[i] == '.')
  165.         vr[i] = '.';
  166.     else {
  167.  
  168.         /* add the current pair of digits with the carry */
  169.         vr[i] = v1[i] + v2[i] + carry - '0';
  170.  
  171.         /* check for carry */
  172.         if (vr[i] > '9') {
  173.         vr[i] -= 10;
  174.         carry = 1;
  175.         }
  176.         else
  177.         carry = 0;
  178.     }
  179.     }
  180.  
  181.     /* add the remaining digits */
  182.     for (; i >= nmax; i--) {
  183.  
  184.     /* add the current digit with the carry */
  185.     vr[i] = vx[i] + carry;
  186.  
  187.     /* check for carry */
  188.     if (vr[i] > '9') {
  189.         vr[i] -= 10;
  190.         carry = 1;
  191.     }
  192.     else
  193.         carry = 0;
  194.     }
  195.  
  196.     /* check for a carry out and shift digits if necessary */
  197.     if (carry == 1) {
  198.  
  199.     /* shift the digits */
  200.     for (i = -nmax; i >= 0; i--)
  201.         result[i+1] = result[i];
  202.     result[0] = '1';
  203.     }
  204. }
  205.  
  206. /* sub - subtract two unsigned numeric strings */
  207. static sub(result,arg1,arg2)
  208.   char *result,*arg1,*arg2;
  209. {
  210.     char *vr,*v1,*v2,*vx;
  211.     int borrow,i,nmin,nmax,nd1,nd2;
  212.  
  213.     /* get number of digits in each argument */
  214.     nd1 = getlen(arg1);
  215.     nd2 = getlen(arg2);
  216.  
  217.     /* compute the address of the last digit + 1 */
  218.     v1 = arg1 + nd1;
  219.     v2 = arg2 + nd2;
  220.  
  221.     /* compute minimum and maximum of nd1 and nd2 */
  222.     if (nd1 < nd2) {
  223.     nmin = -nd1;
  224.     nmax = -nd2;
  225.     vx = v2;
  226.     }
  227.     else {
  228.     nmin = -nd2;
  229.     nmax = -nd1;
  230.     vx = v1;
  231.     }
  232.  
  233.     /* compute the address of the last result digit + 1 */
  234.     vr = result - nmax; vr[0] = 0;
  235.  
  236.     /* initialize the borrow */
  237.     borrow = 0;
  238.  
  239.     /* subtract the digits */
  240.     for (i = -1; i >= nmin; i--) {
  241.  
  242.     /* check for decimal point */
  243.     if (v1[i] == '.')
  244.         vr[i] = '.';
  245.     else {
  246.  
  247.         /* subtract the current pair of digits with the borrow */
  248.         vr[i] = v1[i] - v2[i] - borrow + '0';
  249.  
  250.         /* check for borrow */
  251.         if (vr[i] < '0') {
  252.         vr[i] += 10;
  253.         borrow = 1;
  254.         }
  255.         else
  256.         borrow = 0;
  257.     }
  258.     }
  259.  
  260.     /* subtract the remaining digits */
  261.     for (; i >= nmax; i--) {
  262.  
  263.     /* subtract the current digit with the borrow */
  264.     vr[i] = vx[i] - borrow;
  265.  
  266.     /* check for borrow */
  267.     if (vr[i] < '0') {
  268.         vr[i] += 10;
  269.         borrow = 1;
  270.     }
  271.     else
  272.         borrow = 0;
  273.     }
  274. }
  275.  
  276. /* getsign - get the sign of a numeric string */
  277. static int getsign(parg)
  278.   char **parg;
  279. {
  280.     int sign;
  281.     char *p;
  282.  
  283.     /* eliminate leading spaces */
  284.     while (isspace(**parg))
  285.     *parg += 1;
  286.  
  287.     /* get the sign */
  288.     switch (**parg) {
  289.     case '+':    *parg += 1;
  290.         sign = 1;
  291.         break;
  292.     case '-':    *parg += 1;
  293.         sign = -1;
  294.         break;
  295.     default:    sign = 1;
  296.         break;
  297.     }
  298.  
  299.     /* eliminate leading spaces and zeros */
  300.     while (isspace(**parg) || **parg == '0')
  301.     *parg += 1;
  302.  
  303.     /* if the value is zero, make sure that the sign is positive */
  304.     switch (**parg) {
  305.     case 0:    sign = 1;
  306.         break;
  307.     case '.':    for (p = *parg + 1; *p == '0'; p++)
  308.             ;
  309.         if (*p == 0)
  310.             sign = 1;
  311.         break;
  312.     }
  313.  
  314.     /* return the sign */
  315.     return (sign);
  316. }
  317.  
  318. /* getlen - get the length of a numeric string */
  319. static int getlen(arg)
  320.   char *arg;
  321. {
  322.     int len;
  323.  
  324.     /* get the length of the string */
  325.     len = strlen(arg);
  326.  
  327.     /* eliminate trailing spaces */
  328.     while (isspace(arg[len-1]))
  329.     len -= 1;
  330.  
  331.     /* return the length */
  332.     return (len);
  333. }
  334.  
  335. /* compare - compare two unsigned numeric strings */
  336. static int compare(arg1,arg2)
  337.   char *arg1,*arg2;
  338. {
  339.     int len1,len2;
  340.  
  341.     /* compare lengths */
  342.     if ((len1 = getlen(arg1)) != (len2 = getlen(arg2)))
  343.     if (len1 < len2)
  344.         return (-1);
  345.     else
  346.         return (1);
  347.  
  348.     /* compare strings */
  349.     return (strcmp(arg1,arg2));
  350. }
  351.